package com.by.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by.constants.RedisLuaScriptConstant;
import com.by.enums.ErrorCode;
import com.by.enums.LuaStatusEnum;
import com.by.exception.BusinessException;
import com.by.mapper.ThumbMapper;
import com.by.model.dto.thumb.DoThumbDTO;
import com.by.model.entity.Thumb;
import com.by.model.entity.User;
import com.by.service.ThumbService;
import com.by.service.UserService;
import com.by.utils.RedisKeyUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Arrays;

/**
 * @author lzh
 */
@Service("thumbService")
@RequiredArgsConstructor
public class ThumbServiceRedisImpl extends ServiceImpl<ThumbMapper, Thumb> implements ThumbService {

    private final UserService userService;
    private final RedisTemplate<String, Object> redisTemplate;

    @Override
    public Boolean doThumb(DoThumbDTO doThumbDTO, HttpServletRequest request) {
        if (doThumbDTO == null || doThumbDTO.getBlogId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Long blogId = doThumbDTO.getBlogId();
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }

        String timeScale = getTimeScale();
        // Redis Key
        String userThumbKey = RedisKeyUtils.getUserThumbKey(loginUser.getId());
        String tempThumbKey = RedisKeyUtils.getTempThumbKey(timeScale);

        // 执行Lua脚本
        Long result = redisTemplate.execute(
                RedisLuaScriptConstant.THUMB_SCRIPT,
                Arrays.asList(tempThumbKey, userThumbKey),
                loginUser.getId(),
                blogId
        );

        if (LuaStatusEnum.FAIL.getValue().equals(result)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户已点赞");
        }
        // 更新成功才执行
        return LuaStatusEnum.SUCCESS.getValue().equals(result);
    }

    @Override
    public Boolean undoThumb(DoThumbDTO doThumbDTO, HttpServletRequest request) {
        if (doThumbDTO == null || doThumbDTO.getBlogId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Long blogId = doThumbDTO.getBlogId();
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }

        String timeScale = getTimeScale();
        // Redis Key
        String userThumbKey = RedisKeyUtils.getUserThumbKey(loginUser.getId());
        String tempThumbKey = RedisKeyUtils.getTempThumbKey(timeScale);

        // 执行Lua脚本
        Long result = redisTemplate.execute(
                RedisLuaScriptConstant.UN_THUMB_SCRIPT,
                Arrays.asList(tempThumbKey, userThumbKey),
                loginUser.getId(),
                blogId
        );

        if (LuaStatusEnum.FAIL.getValue().equals(result)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户未点赞");
        }
        // 更新成功才执行
        return LuaStatusEnum.SUCCESS.getValue().equals(result);
    }

    @Override
    public Boolean hasThumb(Long blogId, Long userId) {
        return redisTemplate.opsForHash()
                .hasKey(RedisKeyUtils.getUserThumbKey(userId), blogId.toString());
    }

    private String getTimeScale() {
        DateTime nowDate = DateUtil.date();
        // 获取到当前时间戳最近的整数秒，如15:46:23 => 15:46:20
        return DateUtil.format(nowDate, "HH:mm:") + (DateUtil.second(nowDate) / 10) * 10;
    }
}




